
module jade.tpl.js.StopWatch ;

import jade.tpl.Template ;

static DStopWatch_Constructor	stopwatch_constructor  ;
static DStopWatch_Prototype	stopwatch_prototype ;

final class DStopWatch_Constructor : Dfunction {

	final this() {
		super(0, Dfunction_prototype);
	}
	

	final override void* Construct(CallContext *cc, Value *ret, Value[] args)
	{
		int len = 1024;
		int step = 1024 ;
		if( args.length > 0 && args[0].isNumber ) {
			len	= cast(int) args[0].toInteger ;
			if( len < 512 || len > 102400 ) {
				len	=  1024 ;
			}
			if( args.length > 1 && args[1].isNumber ) {
				step	= cast(int) args[1].toInteger ;
				if( step < 512 || step > 102400 ) {
					step	=  1024 ;
				}
			}
		}
		
		DStopWatch_Object obj	= new DStopWatch_Object( stopwatch_prototype ) ;
		ret.putVobject(obj);
		return null;
	}
	
	final override void* Call(CallContext *cc, Dobject othis, Value* ret, Value[] args){

		return null;
	}
	
}

final class DStopWatch_Prototype : Dobject {

	final this(Dobject prototype){
		super(prototype);
		
		static enum NativeFunctionData nfd[] =
		[
		    {"start", &StopWatch_prototype_start, 0} ,
		    {"stop", &StopWatch_prototype_stop, 0} ,
		    {"reset", &StopWatch_prototype_reset, 0} ,
		    {"usecs", &StopWatch_prototype_usecs, 0} ,
		];

		DnativeFunction.init(this, nfd, DontDelete | ReadOnly );
	}
	
	static void* StopWatch_prototype_start(Dobject pthis, CallContext* cc, Dobject othis, Value* ret, Value[] argv) {
		static const func_name = "stopwatch.start";
		ErrInfo errinfo;
		DStopWatch_Object _this	= cast(DStopWatch_Object) othis ;
		if( _this is null ) {
                	return RuntimeError(&errinfo, ERR_TYPE_ERROR , func_name);
		}
		_this.sw.start;
		ret.putVobject(othis);
		return null ;
	}
	
	static void* StopWatch_prototype_stop(Dobject pthis, CallContext* cc, Dobject othis, Value* ret, Value[] argv) {
		static const func_name = "stopwatch.stop";
		ErrInfo errinfo;
		DStopWatch_Object _this	= cast(DStopWatch_Object) othis ;
		if( _this is null ) {
                	return RuntimeError(&errinfo, ERR_TYPE_ERROR , func_name);
		}
		_this.sw.stop;
		ret.putVobject(othis);
		return null ;
	}
	
	static void* StopWatch_prototype_reset(Dobject pthis, CallContext* cc, Dobject othis, Value* ret, Value[] argv) {
		static const func_name = "stopwatch.reset";
		ErrInfo errinfo;
		DStopWatch_Object _this	= cast(DStopWatch_Object) othis ;
		if( _this is null ) {
                	return RuntimeError(&errinfo, ERR_TYPE_ERROR , func_name);
		}
		_this.sw.reset;
		ret.putVobject(othis);
		return null ;
	}
	
	static void* StopWatch_prototype_usecs(Dobject pthis, CallContext* cc, Dobject othis, Value* ret, Value[] argv) {
		static const func_name = "stopwatch.usecs";
		ErrInfo errinfo;
		DStopWatch_Object _this	= cast(DStopWatch_Object) othis ;
		if( _this is null ) {
                	return RuntimeError(&errinfo, ERR_TYPE_ERROR , func_name);
		}
		ret.putVnumber(_this.sw.peek.usecs);
		return null ;
	}
	
}

final class DStopWatch_Object : Dobject {
	
	private StopWatch sw ;
	
	final this(Dobject prototype){
		super(prototype);
	}
	
	static void Init(Dobject obj){
		if( stopwatch_constructor !is null ) {
			return ;
		}
		stopwatch_constructor	= new DStopWatch_Constructor ;
		stopwatch_prototype	= new DStopWatch_Prototype(Dobject_prototype) ;
		
      		stopwatch_constructor.Put(TEXT_prototype, stopwatch_prototype, DontEnum | DontDelete | ReadOnly);
		obj.Put("StopWatch", stopwatch_constructor, DontEnum | DontDelete | ReadOnly);
	}
	
	final override void* Call(CallContext *cc, Dobject othis, Value* ret, Value[] args){
		ret.putVnumber(sw.peek.msecs);
		return null;
	}
	
}

